C4 Model
The C4 model is a way of drawing software architecture at four levels of detail, so that each diagram has one audience and one purpose. It was created by Simon Brown and is deliberately informal — there is no compliance to achieve.
It earns its place in health architecture because the alternative, in practice, is a single diagram containing forty boxes that nobody can read and nobody maintains.
| Level | Shows | Audience |
|---|---|---|
| 1 — System context | Your system, its users, and the systems it talks to | Everyone, including non-technical stakeholders |
| 2 — Container | The deployable/runnable pieces inside it and how they communicate | Architects, developers, operations |
| 3 — Component | The major structural pieces inside one container | Developers working on that container |
| 4 — Code | Classes, schemas — usually generated, rarely drawn | Occasionally useful, often skipped |
Most health architecture work lives at levels 1 and 2. Level 3 is worth drawing for the one or two containers that are genuinely complex. Level 4 is almost always a waste of effort — generate it if you need it.
Level 1 — System context
One box for your system, surrounded by the people and systems it interacts with. No internals.
Example: an antenatal care EMR
┌────────────┐ ┌──────────────────┐
│ Midwife │ │ Programme │
│ (facility)│ │ manager (dist.) │
└─────┬──────┘ └────────┬─────────┘
│ records ANC contact │ reviews coverage
▼ ▼
┌───────────────────────────────────────────┐
│ ANC EMR system │
│ Registers pregnancies, records contacts, │
│ schedules follow-up, flags danger signs │
└───┬───────────┬──────────────┬────────────┘
│ │ │
│ patient │ aggregate │ lab orders
│ identity │ indicators │ + results
▼ ▼ ▼
┌────────────┐ ┌─────────┐ ┌──────────────┐
│ Client │ │ DHIS2 │ │ Laboratory │
│ Registry │ │ (HMIS) │ │ system │
└────────────┘ └─────────┘ └──────────────┘
The value of this diagram is political as much as technical: it makes visible that the EMR does not own patient identity, and that someone must therefore operate a client registry.
Level 2 — Container
"Container" here means a separately runnable thing — an application, a service, a database, a message broker. Not necessarily a Docker container, though it often is one.
Example: a national health information exchange
Point-of-service systems (EMR, LMIS, CHW app, lab)
│ HTTPS / FHIR, HL7 v2
▼
┌──────────────────────────────────────────────────────┐
│ Interoperability layer │
│ ┌────────────────┐ ┌──────────────┐ │
│ │ API gateway │→ │ Mediators │ │
│ │ authN/authZ, │ │ transform, │ │
│ │ routing, audit │ │ orchestrate │ │
│ └───────┬────────┘ └──────┬───────┘ │
│ │ │ │
│ ┌───────▼──────┐ ┌──────▼───────┐ │
│ │ Audit store │ │ Message queue│ │
│ └──────────────┘ └──────────────┘ │
└───────┬───────────────┬──────────────┬───────────────┘
▼ ▼ ▼
┌──────────────┐ ┌─────────────┐ ┌──────────────────┐
│ Client │ │ Facility │ │ Terminology │
│ registry │ │ registry │ │ service │
│ + its DB │ │ + its DB │ │ + its DB │
└──────────────┘ └─────────────┘ └──────────────────┘
│
▼
┌──────────────────────────┐ ┌──────────────────┐
│ Shared health record │──▶│ Analytics / │
│ (FHIR server + DB) │ │ data warehouse │
└──────────────────────────┘ └──────────────────┘
Annotate each arrow with protocol, format and direction — HTTPS / FHIR R4 Bundle, synchronous is a useful label; an unlabelled arrow is decoration.
Compare with the component structure in OpenHIE: the C4 container diagram is where a reference architecture becomes a deployable design.
Level 3 — Component
Inside one container. Draw this only where the internal structure is a real design decision.
Example: inside the client registry
┌──────────────────────────────────────────────────┐
│ Client registry │
│ │
│ ┌───────────────┐ ┌────────────────────────┐ │
│ │ FHIR API │──▶│ Matching engine │ │
│ │ Patient, │ │ deterministic rules + │ │
│ │ $match │ │ probabilistic scoring │ │
│ └───────────────┘ └───────────┬────────────┘ │
│ │ │
│ ┌─────────────────────────┼────────────┐ │
│ ▼ ▼ ▼ │
│ ┌───────────┐ ┌──────────────┐ ┌───────────┐
│ │ Golden │ │ Review queue │ │ Link/ │
│ │ record │ │ (human │ │ unlink │
│ │ store │ │ adjudication)│ │ audit log│
│ └───────────┘ └──────────────┘ └───────────┘
└──────────────────────────────────────────────────┘
The review queue is the component people forget, and the reason MPI projects stall.
Level 4 — Code
Class or schema diagrams. Generate from the source; do not maintain by hand.
Supplementary diagrams
C4 is often paired with three others:
- Deployment diagram — mapping containers onto infrastructure (nodes, regions, networks). Essential for availability and data residency conversations.
- Sequence diagram — for a single interaction over time. The clearest way to explain a SMART on FHIR launch or a patient-identity lookup.
- Data flow diagram — what personal data moves where, which is the input to a privacy impact assessment.
Applying C4 across the ecosystem
| System | Level 1 shows | Level 2 shows |
|---|---|---|
| EMR | Clinicians, patients, lab, HIE, HMIS | Web app, API, database, integration adapter |
| HIE | All point-of-service systems, registries, regulator | Gateway, mediators, queue, audit, registries |
| FHIR platform | Client apps, identity provider, source systems | FHIR server, terminology server, auth server, storage |
| DHIS2 | Facilities, districts, programmes, ministry | Web app, analytics tables, database, import/export |
| National platform | Ministry, provinces, citizens, other government sectors | Shared services (identity, exchange, registries, consent) |
| AI platform | Clinicians, data stewards, model owners | Inference service, model registry, feature/vector store, monitoring, audit |
Practical rules
- Every diagram gets a title, a legend and a date. An undated architecture diagram is folklore.
- One level per diagram. Mixing containers and components is the most common way these become unreadable.
- Keep the notation boring. Boxes, arrows, labels. Colour carries at most one meaning, stated in the legend.
- Diagram what exists and what is proposed as separate diagrams, clearly labelled. Merging them is how a roadmap gets mistaken for a system.
- Store diagrams as text where possible — Mermaid, PlantUML or Structurizr DSL — so they diff in version control alongside the ADR that explains them.
Tooling
| Tool | Notes |
|---|---|
| Structurizr | C4-native, diagrams-as-code from a single model |
| PlantUML (+ C4-PlantUML macros) | Text-based, renders anywhere, no service dependency |
| Mermaid | Renders natively in GitHub and many docs sites; simplest to sustain |
| draw.io / diagrams.net | Free-form; easiest for people who will not write DSL |
Choose the one your team will actually update six months from now. That is the only criterion that matters.
References
- C4 model — https://c4model.com/
- Structurizr — https://structurizr.com/
- C4-PlantUML — https://github.com/plantuml-stdlib/C4-PlantUML
- Mermaid — https://mermaid.js.org/